package com.github.shuaidd.service.transfer;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.XmlUtil;
import com.github.shuaidd.model.dto.*;
import com.github.shuaidd.model.vo.ProcessModelVO;
import com.github.shuaidd.service.util.XMLUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.io.Files;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;

/**
 * 描述
 *
 * @author ddshuai
 * @date 2020-08-06 10:16
 **/

@Slf4j
@Service
public class TransferService {

    /**
     * 转换lwf-xml 为bpmn
     */
    public void transfer() throws FileNotFoundException {
        File rootPath = ResourceUtils.getFile("classpath:/needTrasfer");
        if (rootPath.isDirectory()) {
            for (File file : Objects.requireNonNull(rootPath.listFiles())) {
                log.info("文件名称：{}", file.getName());
                BpmnXmlDTO xml = getInitXml();
                Document document = XmlUtil.readXML(file);
                NodeList nodeList = document.getChildNodes();
                int lgh = nodeList.getLength();
                for (int i = 0; i < lgh; i++) {
                    Node rootNode = nodeList.item(i);
                    BpmnProcessDTO process = new BpmnProcessDTO();
                    process.setName(rootNode.getNodeValue());
                    process.setId(Files.getNameWithoutExtension(file.getName()));
                    xml.setBpmnProcess(process);

                    List<SequenceFlowDTO> sequenceFlows = Lists.newArrayList();
                    process.setSequenceFlows(sequenceFlows);
                    log.info("根节点名称-{}-{}", rootNode.getNodeName(), rootNode.getNodeValue() == null ? '无' : rootNode.getNodeValue());
                    NodeList activityNodeList = rootNode.getChildNodes();
                    int activityLgh = activityNodeList.getLength();

                    List<TaskDTO> tasks = Lists.newArrayList();
                    Map<String, List<String>> incomingMap = Maps.newHashMap();
                    for (int i1 = 0; i1 < activityLgh; i1++) {
                        Node actNode = activityNodeList.item(i1);
                        if (!"Activity".equals(actNode.getNodeName())) {
                            //是空行就直接跳过
                            continue;
                        }
                        log.error("##################################################Activity节点定义开始##################################################");
                        String code = getAttrValue(actNode, "code");
                        if ("start".equals(code)) {
                            StartEventDTO startEvent = buildStartEventDTO(actNode, incomingMap, sequenceFlows);
                            process.setStartEvent(startEvent);
                        } else if ("end".equals(code)) {
                            EndEventDTO endEvent = buildEndEventDTO(actNode, incomingMap);
                            process.setEndEvent(endEvent);
                        } else {
                            //用户任务
                            TaskDTO task = buildTaskDto(actNode, incomingMap, sequenceFlows);
                            tasks.add(task);
                        }
                    }

                    process.setUserTasks(tasks);
                }
                diagram(xml);
                log.info("待转换的文件名-->> {},\n {}", file.getName(), XMLUtil.convertToXml(xml));
                break;
            }
        }
    }

    public BpmnXmlDTO transfer(String fileCode) throws FileNotFoundException {
        File rootPath = ResourceUtils.getFile("classpath:/needTrasfer");
        String path = rootPath.getAbsolutePath() + "/" + fileCode + ".xml";
        File file = new File(path);
        BpmnXmlDTO xml = getInitXml();
        Document document = XmlUtil.readXML(file);
        NodeList nodeList = document.getChildNodes();
        int lgh = nodeList.getLength();
        for (int i = 0; i < lgh; i++) {
            Node rootNode = nodeList.item(i);
            BpmnProcessDTO process = new BpmnProcessDTO();
            process.setName(getAttrValue(rootNode, "name"));
            process.setId(Files.getNameWithoutExtension(file.getName()));
            xml.setBpmnProcess(process);

            List<SequenceFlowDTO> sequenceFlows = Lists.newArrayList();
            process.setSequenceFlows(sequenceFlows);
            log.info("根节点名称-{}-{}", rootNode.getNodeName(), rootNode.getNodeValue() == null ? '无' : rootNode.getNodeValue());
            NodeList activityNodeList = rootNode.getChildNodes();
            int activityLgh = activityNodeList.getLength();

            List<TaskDTO> tasks = Lists.newArrayList();
            Map<String, List<String>> incomingMap = Maps.newHashMap();
            for (int i1 = 0; i1 < activityLgh; i1++) {
                Node actNode = activityNodeList.item(i1);
                if (!"Activity".equals(actNode.getNodeName())) {
                    //是空行就直接跳过
                    continue;
                }
                log.error("##################################################Activity节点定义开始##################################################");
                String code = getAttrValue(actNode, "code");
                if ("start".equals(code)) {
                    StartEventDTO startEvent = buildStartEventDTO(actNode, incomingMap, sequenceFlows);
                    process.setStartEvent(startEvent);
                } else if ("end".equals(code)) {
                    EndEventDTO endEvent = buildEndEventDTO(actNode, incomingMap);
                    process.setEndEvent(endEvent);
                } else {
                    //用户任务
                    TaskDTO task = buildTaskDto(actNode, incomingMap, sequenceFlows);
                    tasks.add(task);
                }
            }

            process.setUserTasks(tasks);
        }
        diagram(xml);
        log.info("待转换的文件名-->> {},\n {}", file.getName(), XMLUtil.convertToXml(xml));
        return xml;
    }

    private EndEventDTO buildEndEventDTO(Node actNode, Map<String, List<String>> incomingMap) {
        String code = getAttrValue(actNode, "code");
        String name = getAttrValue(actNode, "name");
        EndEventDTO endEvent = new EndEventDTO();
        endEvent.setName(name);
        endEvent.setId(code);
        endEvent.setIncoming(incomingMap.get(code));

        return endEvent;
    }

    private StartEventDTO buildStartEventDTO(Node actNode, Map<String, List<String>> incomingMap, List<SequenceFlowDTO> sequenceFlows) {
        String code = getAttrValue(actNode, "code");
        String name = getAttrValue(actNode, "name");
        StartEventDTO startEvent = new StartEventDTO();
        startEvent.setName(name);
        startEvent.setId(code);
        //获取流向
        NodeList transitions = actNode.getChildNodes();
        List<String> outs = Lists.newArrayList();
        for (int i2 = 0; i2 < transitions.getLength(); i2++) {
            Node transition = transitions.item(i2);
            if (!"transition".equals(transition.getNodeName())) {
                continue;
            }
            SequenceFlowDTO sequenceFlowDTO = buildSequenceFlowDTO(transition, code);
            sequenceFlows.add(sequenceFlowDTO);
            outs.add(sequenceFlowDTO.getId());
            putValue(incomingMap, getAttrValue(transition, "to"), sequenceFlowDTO.getId());
        }
        startEvent.setOuts(outs);

        return startEvent;
    }

    private TaskDTO buildTaskDto(Node actNode, Map<String, List<String>> incomingMap, List<SequenceFlowDTO> sequenceFlows) {
        TaskDTO task = new TaskDTO();
        String code = getAttrValue(actNode, "code");
        String name = getAttrValue(actNode, "name");
        task.setIncoming(incomingMap.get(code));
        task.setName(name);
        task.setId(code);
        NodeList transitions = actNode.getChildNodes();
        List<String> outs = Lists.newArrayList();
        for (int i2 = 0; i2 < transitions.getLength(); i2++) {
            Node transition = transitions.item(i2);
            if ("transition".equals(transition.getNodeName())) {
                if (Objects.equals(getAttrValue(transition, "to"), code)) {
                    //死循环 处理掉
                    continue;
                }
                SequenceFlowDTO sequenceFlowDTO = buildSequenceFlowDTO(transition, code);
                sequenceFlows.add(sequenceFlowDTO);
                outs.add(sequenceFlowDTO.getId());
                putValue(incomingMap, getAttrValue(transition, "to"), sequenceFlowDTO.getId());
            }
            if ("Participant".equals(transition.getNodeName())) {
                ExtensionElementDTO extensionElementDTO = new ExtensionElementDTO();
                task.setExtensionElement(extensionElementDTO);
                List<PropertyDTO> propertys = Lists.newArrayList();
                extensionElementDTO.setProperties(propertys);
                NamedNodeMap namedNodeMap = transition.getAttributes();
                if (namedNodeMap != null) {
                    int attrLeg = namedNodeMap.getLength();
                    for (int i4 = 0; i4 < attrLeg; i4++) {
                        Node attrNode = namedNodeMap.item(i4);
                        PropertyDTO propertyDTO = new PropertyDTO();
                        propertyDTO.setName(attrNode.getNodeName());
                        propertyDTO.setValue(attrNode.getNodeValue());
                        propertys.add(propertyDTO);
                        log.info("节点属性-{}->{}", attrNode.getNodeName(), attrNode.getNodeValue());
                    }
                }
            }
        }
        task.setOuts(outs);
        return task;
    }

    private SequenceFlowDTO buildSequenceFlowDTO(Node transition, String source) {
        String id = source + "-2-" + getAttrValue(transition, "to");
        String name = getAttrValue(transition, "name");
        String target = getAttrValue(transition, "to");
        SequenceFlowDTO sequenceFlowDTO = new SequenceFlowDTO();
        sequenceFlowDTO.setId(id);
        sequenceFlowDTO.setName(name);
        sequenceFlowDTO.setSourceRef(source);
        sequenceFlowDTO.setTargetRef(target);
        //获取分支跳转条件
        NodeList conditions = transition.getChildNodes();
        for (int i = 0; i < conditions.getLength(); i++) {
            Node condition = conditions.item(i);
            if ("condition".equals(condition.getNodeName())) {
                if (StringUtils.isEmpty(condition.getTextContent())) {
                    continue;
                }
                ConditionExpressionDTO expression = new ConditionExpressionDTO();
                expression.setType("bpmn:tFormalExpression");
                expression.setLanguage("javascript");
                expression.setValue(condition.getTextContent());
                sequenceFlowDTO.setConditionExpression(expression);
            }
        }

        return sequenceFlowDTO;
    }

    private void putValue(Map<String, List<String>> map, String key, String value) {
        if (map.get(key) == null) {
            map.put(key, Lists.newArrayList(value));
        } else {
            map.get(key).add(value);
        }
    }

    /**
     * 流程图形化
     *
     * @param xml
     */
    private void diagram(BpmnXmlDTO xml) {
        //找出开始到结束的全部的流向
        List<LinkedList<Object>> flows = Lists.newArrayList();
        //所有的任务节点的集合
        HashMap<String, TaskDTO> taskMap = Maps.newHashMap();
        //所有的流向的线的集合
        HashMap<String, SequenceFlowDTO> flowSeqMap = Maps.newHashMap();
        //所有已经图形化设置过的节点
        HashMap<String, Object> allDiagramNodes = Maps.newHashMap();
        //节点的进线数量
        HashMap<String, Integer> nodeLineInCountMap = Maps.newHashMap();
        //节点的出线数量
        HashMap<String, Integer> nodeLineOutCountMap = Maps.newHashMap();

        for (TaskDTO userTask : xml.getBpmnProcess().getUserTasks()) {
            taskMap.put(userTask.getId(), userTask);
        }

        for (SequenceFlowDTO sequenceFlow : xml.getBpmnProcess().getSequenceFlows()) {
            flowSeqMap.put(sequenceFlow.getId(), sequenceFlow);
        }

        List<LinkedList<Object>> allFlows = nextDiagram(flows, taskMap, flowSeqMap, xml);
        log.info("所有的流向->{}", allFlows.size());
        LinkedList<Object> maxList = getMaxLengthFlow(allFlows);

        DiagramDTO diagram = new DiagramDTO();
        diagram.setId(RandomStringUtils.random(36, true, false));
        DiagramPlaneDTO diagramPlane = new DiagramPlaneDTO();
        diagramPlane.setId(RandomStringUtils.random(36, true, false));
        diagramPlane.setBpmnElement(xml.getBpmnProcess().getId());
        diagram.setDiagramPlane(diagramPlane);
        List<DiagramEdgeDTO> diagramEdges = Lists.newArrayList();
        List<DiagramShapeDTO> shapes = Lists.newArrayList();
        diagramPlane.setDiagramShapes(shapes);
        diagramPlane.setDiagramEdges(diagramEdges);

        handleDiagram(maxList, allDiagramNodes, shapes, diagramEdges, nodeLineInCountMap, nodeLineOutCountMap);
        //全部流向都画上去
        for (LinkedList<Object> allFlow : allFlows) {
            if (allFlow == maxList) {
                //已经在上面画了一次
                continue;
            }
            handleDiagram(allFlow, allDiagramNodes, shapes, diagramEdges, nodeLineInCountMap, nodeLineOutCountMap);
        }
        xml.setDiagram(diagram);
    }

    private LinkedList<Object> getMaxLengthFlow(List<LinkedList<Object>> allFlows) {
        LinkedList<Object> maxList = Lists.newLinkedList();
        for (LinkedList<Object> allFlow : allFlows) {
            if (maxList.size() < allFlow.size()) {
                maxList = allFlow;
            }
            StringBuilder builder = new StringBuilder();
            allFlow.forEach((node) -> {
                if (node instanceof StartEventDTO) {
                    builder.append(((StartEventDTO) node).getName()).append("-->");
                }

                if (node instanceof TaskDTO) {
                    builder.append(((TaskDTO) node).getName()).append("-->");
                }

                if (node instanceof EndEventDTO) {
                    builder.append(((EndEventDTO) node).getName());
                }
            });
            log.info("审批路径*****{}", builder.toString());
        }
        return maxList;
    }

    private void handleDiagram(LinkedList<Object> maxList, HashMap<String, Object> allDiagramNodes,
                               List<DiagramShapeDTO> shapes,
                               List<DiagramEdgeDTO> diagramEdges,
                               HashMap<String, Integer> nodeLineInCountMap, HashMap<String, Integer> nodeLineOutCountMap) {
        for (Object node : maxList) {

            if (node instanceof StartEventDTO) {
                String id = ((StartEventDTO) node).getId();
                if (allDiagramNodes.get("shape-" + id) != null) {
                    //节点已存在 不需要管了
                    continue;
                }
                DiagramShapeDTO diagramShape = buildDiagramShapeDTO(id, 92, 172, 36, 36);
                allDiagramNodes.put("shape-" + id, diagramShape);
                shapes.add(diagramShape);
            }

            if (node instanceof SequenceFlowDTO) {
                SequenceFlowDTO sequenceFlow = (SequenceFlowDTO) node;
                String id = sequenceFlow.getId();
                if (allDiagramNodes.get("edge-" + id) != null) {
                    //节点已存在 不需要管了
                    continue;
                }

                Object object = allDiagramNodes.get("shape-" + sequenceFlow.getTargetRef());
                DiagramShapeDTO diagramShape = null;
                if (object != null) {
                    diagramShape = (DiagramShapeDTO) object;
                }
                boolean isFourPoint = false;

                Integer inCount = nodeLineInCountMap.get(sequenceFlow.getTargetRef()) == null ? 0 : nodeLineInCountMap.get(sequenceFlow.getTargetRef());
                nodeLineInCountMap.put(sequenceFlow.getTargetRef(), inCount + 1);

                Integer outCount = nodeLineOutCountMap.get(sequenceFlow.getSourceRef()) == null ? 0 : nodeLineOutCountMap.get(sequenceFlow.getSourceRef());
                nodeLineOutCountMap.put(sequenceFlow.getSourceRef(), outCount + 1);

                if (inCount > 0 || outCount > 0) {
                    isFourPoint = true;
                }

                //找出起始坐标
                DiagramShapeDTO sourceShape = (DiagramShapeDTO) allDiagramNodes.get("shape-" + sequenceFlow.getSourceRef());
                if (isFourPoint) {
                    int startX = sourceShape.getBound().getWidth() == 36 ? sourceShape.getBound().getX() + 18 : sourceShape.getBound().getX() + 50;
                    int startY = sourceShape.getBound().getWidth() == 36 ? sourceShape.getBound().getY() + 36 : sourceShape.getBound().getY() + 80;
                    DiagramEdgeDTO diagramEdge = buildDiagramEdgeDTO(id, startX, startY, diagramShape, isFourPoint);
                    allDiagramNodes.put("edge-" + id, diagramEdge);

                    diagramEdges.add(diagramEdge);
                } else {
                    int startX = sourceShape.getBound().getWidth() == 36 ? sourceShape.getBound().getX() + 36 : sourceShape.getBound().getX() + 100;
                    int startY = sourceShape.getBound().getWidth() == 36 ? sourceShape.getBound().getY() + 18 : sourceShape.getBound().getY() + 40;
                    DiagramEdgeDTO diagramEdge = buildDiagramEdgeDTO(id, startX, startY, diagramShape, isFourPoint);
                    allDiagramNodes.put("edge-" + id, diagramEdge);

                    diagramEdges.add(diagramEdge);
                }

            }

            if (node instanceof TaskDTO) {

                TaskDTO task = (TaskDTO) node;
                String id = task.getId();
                List<String> inLines = task.getIncoming();
                if (allDiagramNodes.get("shape-" + id) != null) {
                    //节点已存在 不需要管了
                    continue;
                }
                int x = 0;
                int y = 0;
                for (String inLine : inLines) {
                    DiagramEdgeDTO diagramEdge = (DiagramEdgeDTO) allDiagramNodes.get("edge-" + inLine);
                    if (diagramEdge != null) {
                        DiagramWayPointDTO wayPoint = diagramEdge.getWayPoints().get(diagramEdge.getWayPoints().size() - 1);
                        x = wayPoint.getX();
                        y = wayPoint.getY();
                        break;
                    }
                }

                DiagramShapeDTO diagramShape = buildDiagramShapeDTO(id, x, y - 40, 100, 80);
                allDiagramNodes.put("shape-" + id, diagramShape);
                shapes.add(diagramShape);
            }

            if (node instanceof EndEventDTO) {
                EndEventDTO endEvent = (EndEventDTO) node;
                String id = endEvent.getId();
                if (allDiagramNodes.get("shape-" + id) != null) {
                    //节点已存在 不需要管了
                    continue;
                }
                List<String> inLines = endEvent.getIncoming();

                for (String inLine : inLines) {
                    DiagramEdgeDTO diagramEdge = (DiagramEdgeDTO) allDiagramNodes.get("edge-" + inLine);
                    if (diagramEdge != null) {
                        DiagramWayPointDTO wayPoint = diagramEdge.getWayPoints().get(diagramEdge.getWayPoints().size() - 1);
                        DiagramShapeDTO diagramShape = buildDiagramShapeDTO(id, wayPoint.getX(), wayPoint.getY() - 18, 36, 36);
                        allDiagramNodes.put("shape-" + id, diagramShape);
                        shapes.add(diagramShape);
                        break;
                    }
                }

            }
        }
    }

    /**
     * 构建线条
     *
     * @param bpmnElement 映射的元素
     * @param x           x轴坐标
     * @param y           y轴坐标
     * @return DiagramEdgeDTO
     */
    private DiagramEdgeDTO buildDiagramEdgeDTO(String bpmnElement, int x, int y, DiagramShapeDTO target, boolean fourPoint) {
        DiagramEdgeDTO diagramEdge = new DiagramEdgeDTO();
        diagramEdge.setId(RandomStringUtils.random(36, true, false));
        diagramEdge.setBpmnElement(bpmnElement);
        //流向线上的所有点坐标的集合
        List<DiagramWayPointDTO> diagramWayPoints = Lists.newArrayList();
        //线段是折线
        if (fourPoint) {
            //需要看目标节点是否已经画过了
            if (target != null) {
                int randomY = y + RandomUtil.randomInt(100);
                diagramWayPoints.add(diagramWayPoint(x, y));
                diagramWayPoints.add(diagramWayPoint(x, randomY));
                if (bpmnElement.endsWith("-2-end")) {
                    diagramWayPoints.add(diagramWayPoint(target.getBound().getX() + 18, randomY));
                    diagramWayPoints.add(diagramWayPoint(target.getBound().getX() + 18, target.getBound().getY() + 36));
                } else {
                    diagramWayPoints.add(diagramWayPoint(target.getBound().getX() + 50, randomY));
                    diagramWayPoints.add(diagramWayPoint(target.getBound().getX() + 50, target.getBound().getY() + 80));
                }

            } else {
                int randomY = y + 100 + RandomUtil.randomInt(-10, 10);
                diagramWayPoints.add(diagramWayPoint(x, y));
                diagramWayPoints.add(diagramWayPoint(x + 50, y));
                diagramWayPoints.add(diagramWayPoint(x + 50, randomY));
                diagramWayPoints.add(diagramWayPoint(x + 100, randomY));
            }
        } else {
            //只有两个点的直接画
            diagramWayPoints.add(diagramWayPoint(x, y));
            diagramWayPoints.add(diagramWayPoint(x + 100, y));
        }

        diagramEdge.setWayPoints(diagramWayPoints);
        return diagramEdge;
    }

    /**
     * 坐标点
     *
     * @param x
     * @param y
     * @return
     */
    private DiagramWayPointDTO diagramWayPoint(int x, int y) {
        DiagramWayPointDTO diagramWayPoint = new DiagramWayPointDTO();
        diagramWayPoint.setX(x);
        diagramWayPoint.setY(y);
        return diagramWayPoint;
    }

    /**
     * 构建图形
     *
     * @param bpmnElement 映射的元素
     * @param x           x 轴坐标
     * @param y           y 轴坐标
     * @param width       宽度
     * @param height      高度
     * @return DiagramShapeDTO
     */
    private DiagramShapeDTO buildDiagramShapeDTO(String bpmnElement, int x, int y, int width, int height) {
        DiagramShapeDTO diagramShape = new DiagramShapeDTO();
        diagramShape.setBpmnElement(bpmnElement);
        diagramShape.setId(RandomStringUtils.random(36, true, false));
        DiagramBoundDTO diagramBound = new DiagramBoundDTO();
        diagramBound.setX(x);
        diagramBound.setY(y);
        diagramBound.setWidth(width);
        diagramBound.setHeight(height);
        diagramShape.setBound(diagramBound);
        return diagramShape;
    }

    private List<LinkedList<Object>> nextDiagram(List<LinkedList<Object>> oldList, HashMap<String, TaskDTO> taskMap, HashMap<String, SequenceFlowDTO> flowSeqMap, BpmnXmlDTO xml) {
        if (oldList.size() == 0) {
            StartEventDTO startEvent = xml.getBpmnProcess().getStartEvent();
            for (String out : startEvent.getOuts()) {
                SequenceFlowDTO flow = flowSeqMap.get(out);
                LinkedList<Object> headList = Lists.newLinkedList();
                headList.add(startEvent);//开始节点
                headList.add(flow);//流向
                headList.add(taskMap.get(flow.getTargetRef()));//目的地
                oldList.add(headList);
            }
        }

        Iterator<LinkedList<Object>> iterator = oldList.iterator();
        List<LinkedList<Object>> currents = Lists.newLinkedList();
        boolean endLoop = true;
        while (iterator.hasNext()) {
            LinkedList<Object> flow = iterator.next();

            //最后一个节点是否是结束节点
            if (flow.getLast() instanceof EndEventDTO) {
                //不需要再处理了
                currents.add(flow);
                continue;
            }

            TaskDTO task = (TaskDTO) flow.getLast();
            if (task == null) {
                continue;
            }
            for (String out : task.getOuts()) {
                endLoop = false;
                LinkedList<Object> newerList = Lists.newLinkedList(flow);
                SequenceFlowDTO sequenceFlow = flowSeqMap.get(out);
                newerList.add(sequenceFlow);
                TaskDTO target = taskMap.get(sequenceFlow.getTargetRef());
                if (target != null) {
                    newerList.add(target);
                } else {
                    newerList.add(xml.getBpmnProcess().getEndEvent());
                }

                currents.add(newerList);
            }
        }

        if (!endLoop) {
            log.info("下一个任务节点正在执行");
            nextDiagram(currents, taskMap, flowSeqMap, xml);
        }

        oldList.clear();
        oldList.addAll(currents);
        return currents;
    }

    /**
     * 设置命名空间
     *
     * @return BpmnXmlDTO
     */
    private BpmnXmlDTO getInitXml() {
        BpmnXmlDTO xmlDTO = new BpmnXmlDTO();
        xmlDTO.setId(RandomStringUtils.random(36, true, false));
        xmlDTO.setBpmn("http://www.omg.org/spec/BPMN/20100524/MODEL");
        xmlDTO.setXsi("http://www.w3.org/2001/XMLSchema-instance");
        xmlDTO.setBpmndi("http://www.omg.org/spec/BPMN/20100524/DI");
        xmlDTO.setDc("http://www.omg.org/spec/DD/20100524/DC");
        xmlDTO.setDi("http://www.omg.org/spec/DD/20100524/DI");
        xmlDTO.setTargetNamespace("http://bpmn.io/schema/bpmn");
        xmlDTO.setExporter("bpmn-js (https://demo.bpmn.io)");
        xmlDTO.setCamunda("http://camunda.org/schema/1.0/bpmn");
        xmlDTO.setExporterVersion("7.3.0");
        return xmlDTO;
    }

    private String getAttrValue(Node node, String attrName) {
        NamedNodeMap namedNodeMap = node.getAttributes();
        if (namedNodeMap != null) {
            int attrLeg = namedNodeMap.getLength();
            for (int i = 0; i < attrLeg; i++) {
                Node attrNode = namedNodeMap.item(i);
                log.info("节点属性-{}->{}", attrNode.getNodeName(), attrNode.getNodeValue());
                if (attrName.equals(attrNode.getNodeName())) {
                    return attrNode.getNodeValue();
                }
            }
        }

        return null;
    }

    public List<ProcessModelVO> list() throws FileNotFoundException {
        List<ProcessModelVO> processModels = Lists.newArrayList();
        File rootPath = ResourceUtils.getFile("classpath:/needTrasfer");
        if (rootPath.isDirectory()) {
            for (File file : Objects.requireNonNull(rootPath.listFiles())) {
                ProcessModelVO processModelVO = new ProcessModelVO();
                processModelVO.setModelName(file.getName());
                processModelVO.setModelKey(Files.getNameWithoutExtension(file.getName()));
                processModels.add(processModelVO);
            }
        }
        return processModels;
    }
}
